#include "videolist.h"

#define V_PATH PATH VIDEO_PATH//"/mnt/hgfs/gui/qt-v4l2/res/"//

VideoList::VideoList(QWidget *parent) : QWidget(parent)
{
    setAttribute(Qt::WA_DeleteOnClose);//关闭时回收内存

    setFixedSize(1024, 600);
#if 0
    mQuickView = new QQuickView();
    QWidget *mQuickWidget = QWidget::createWindowContainer(mQuickView, this);
    mQuickWidget->move(0,0);

    mQuickContext = mQuickView->rootContext();// 用于与qml交互
#endif
    connect(KeyThread::Get(), &KeyThread::keyEvent, this, &VideoList::KeyEvent);

    model = new MyModel();

    Delegate *delegate = new Delegate();

    ListView *listView = new ListView(this);
    listView->resize(1024, 600-20);
    listView->move(0, 10);
    listView->setFrameShape(QFrame::NoFrame);
    listView->setAutoFillBackground(false);
    listView->setGridSize(QSize(1024, 90));
    connect(listView, &ListView::ItemClick, this, &VideoList::clicked);
    QScroller::grabGesture(listView, QScroller::TouchGesture);
    listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    listView->setDragEnabled(false);
    listView->setWordWrap(true);
    listView->setWrapping(false);
    listView->setVerticalScrollMode(QListView::ScrollPerPixel);
    listView->setFrameShape(QListView::NoFrame);
    listView->setResizeMode(QListView::Adjust);
    listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    listView->setFocusPolicy(Qt::NoFocus);
    listView->setViewMode(QListView::ListMode);
    listView->setFlow(QListView::TopToBottom);

    listView->setModel(model);
    listView->setItemDelegate(delegate);

    QScroller* scroller = QScroller::scroller(listView);
    QScrollerProperties properties = scroller->scrollerProperties();
    properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);//关闭越区
    scroller->setScrollerProperties(properties);

    loading = new Loading(this);
    loading->setGeometry((1024 - 300)/2, (600-300)/2, 300, 300);
    loading->startLoading(":/res/load.png", 50);

    model->indexChange(0);

    //stack.push();
    addFolderImages(V_PATH);
    //listCurrentFiles(V_PATH);

    connect(this, &VideoList::referList, this, [&](QList<Data_t> list)
    {
        model->clearData();
        foreach(Data_t data, list)
        {
            MyData d;
            d.name = data.name;
            d.isFold = data.type;
            d.path = data.path;
            model->addData(d);
            //log_debug() << "add:" << d.name;
        }

        if(list.size())
        {
            model->indexChange(0);
        }
        else
        {
            QString data = "文件夹为空";
            TipWidget *tipWidget = new TipWidget(data, this);
            tipWidget->show();
            connect(tipWidget, &TipWidget::sigClose, this, [&]
            {
                connect(KeyThread::Get(), &KeyThread::keyEvent, this, &VideoList::KeyEvent);
                addFolderImages();
            });
        }
        loading->stop();
    });
}

VideoList::~VideoList()
{
    //delete mQuickContext;
    //delete mQuickView;

    emit sigClose();
}

void VideoList::KeyEvent(Key_t type, int key)
{
    log_debug() << key << " type=" << type;
    switch (key)
    {
        case 0:
        {
            if(type == KEY_PRESS || type==KEY_REPEAT)
            {
                int index = model->getCurrentIndex();
                int size = model->getSize();
                if(size <= 0)
                    return ;

                if(index == 0)
                    index = size-1;
                else index--;

                model->indexChange(index);
            }
        }
        break;
        case 1:
        {
            if(type == KEY_PRESS || type==KEY_REPEAT)
            {
                int index = model->getCurrentIndex();
                int size = model->getSize();
                if(size <= 0)
                    return ;

                index++;
                index %= size;
                model->indexChange(index);
            }
        }
        break;
        case 2:
        {
            if(type == KEY_PRESS)
            {
                if(model->getCurrentIndex() >= 0)
                {
                    MyData data = model->getCurrentData();
                    log_debug() << data.path << data.name << " type=" << data.isFold;
                    if(data.isFold)
                    {
                        addFolderImages(data.path + "/" + data.name);
                    }
                    else
                    {
                        disconnect(KeyThread::Get(), &KeyThread::keyEvent, this, &VideoList::KeyEvent);
                        VideoWidget *v = new VideoWidget(data.path + "/" + data.name);
                        v->show();
                        connect(v, &VideoWidget::sigClose, this, [&]
                        {
                            connect(KeyThread::Get(), &KeyThread::keyEvent, this, &VideoList::KeyEvent);
                        });
                        connect(v, &VideoWidget::sigChangeVideo, this, &VideoList::slotChangeVideo);
                        connect(this, &VideoList::sigChangeVideo, v, &VideoWidget::slotChangeVideo);
                    }
                }
            }
            else if(type == KEY_LONG_PRESS)
            {
                close();
            }
        }
        break;
    }
}

void VideoList::clicked(const QModelIndex &index)
{
    model->indexChange(index.row());

    if(model->getCurrentIndex() >= 0)
    {
        MyData data = model->getCurrentData();
        log_debug() << data.path << data.name << " type=" << data.isFold;
#if 1
        if(data.isFold)
        {
            addFolderImages(data.path + "/" + data.name);
        }
        else
        {
            disconnect(KeyThread::Get(), &KeyThread::keyEvent, this, &VideoList::KeyEvent);
            VideoWidget *v = new VideoWidget(data.path + "/" + data.name);
            v->show();
            connect(v, &VideoWidget::sigClose, this, [&]
            {
                connect(KeyThread::Get(), &KeyThread::keyEvent, this, &VideoList::KeyEvent);
            });
            connect(v, &VideoWidget::sigChangeVideo, this, &VideoList::slotChangeVideo);
            connect(this, &VideoList::sigChangeVideo, v, &VideoWidget::slotChangeVideo);
        }
#endif
    }
}

void VideoList::addFolderImages(QString path)
{
    if(path.isEmpty())
    {
        log_debug() <<  "size=" << stack.size();
        stack.pop();
        if(stack.size() > 0)
        {
            path = stack.last();
        }
        else
        {
            close();
            return ;
        }
    }
    else
    {
        stack.push_back(path);
    }

    log_debug() << path;
    std::thread([&, path]{

        QList<Data_t> list;
        QDir directory(path);

        // 遍历目录下的所有条目（包括文件和文件夹）
        QFileInfoList fileList = directory.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
        foreach (QFileInfo fileInfo, fileList)
        {
            if (fileInfo.isDir())
            {
                // 处理文件夹
                //qDebug() << "文件夹：" << fileInfo.fileName();
                Data_t data;
                data.name = fileInfo.fileName();
                data.type = QT_FOLD;
                data.path = path;
                list.push_back(data);
            }
            else if (fileInfo.isFile() && fileInfo.suffix().toLower() == "mp4")
            {
                // 处理MP4文件
                //qDebug() << "MP4文件：" << fileInfo.fileName();
                Data_t data;
                data.name = fileInfo.fileName();
                data.type = QT_FILE;
                data.path = path;
                list.push_back(data);
            }
        }

        qSort(list.begin(), list.end(), [&](const Data_t &d1, const Data_t &d2){
            if(d1.type < d2.type)
            {
                return true;
            }
        });

        for(int i=0; i<list.size(); i++)
        {
            log_debug() << list.at(i).name;
        }

        emit referList(list);
    }).detach();
}

void VideoList::listCurrentFiles(QString root)
{
    std::string path = root.toStdString();
    DIR *dir;
    struct dirent *ptr;
    if ((dir = opendir(path.c_str())) == NULL)
    {
        log_debug() << "SearchList dir error:" << path.c_str();
        return ;
    }

    while ((ptr = readdir(dir)) != NULL)
    {
        if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
        {
            continue;
        }

        struct stat pStat;
        std::string tempPath = root.toStdString() + "/" + ptr->d_name;
        stat(tempPath.c_str(), &pStat);

        log_debug() << "SearchList dir name:" << tempPath.c_str() << " st_mode:" << pStat.st_mode;

        bool flag = false;
        QString path = QString::fromStdString(tempPath);


        if (__S_IFDIR & pStat.st_mode)
        {
            log_debug() << ptr->d_name;
        }
        else if (__S_IFREG & pStat.st_mode)
        {
            flag = false;
            std::cout << ptr->d_name << std::endl;
        }
    }
}

void VideoList::slotChangeVideo(int dir)
{
    int index = model->getCurrentIndex();
    int size = model->getSize();
    if(size <= 0)
        return ;

    if(dir == 0)//last
    {
        if(index == 0)
            index = size-1;
        else index--;
    }
    else
    {
        index++;
        index %= size;
    }
    model->indexChange(index);
    MyData data = model->getCurrentData();
    if(data.isFold)
    {
        slotChangeVideo(dir);
    }
    else
        emit sigChangeVideo(data.path + "/" + data.name);
}
